package com.ruoyi.training.service.impl;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.examination.domain.*;
import com.ruoyi.examination.dto.ExamPaperInfoDto;
import com.ruoyi.examination.dto.ExaminationResultDto;
import com.ruoyi.examination.vo.AnswerVo;
import com.ruoyi.examination.vo.ExaminationResultVo;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.training.domain.ClassStudent;
import com.ruoyi.training.domain.ExamSchedule;
import com.ruoyi.training.domain.Students;
import com.ruoyi.training.domain.TrainingClass;
import com.ruoyi.training.dto.registration.RegistrationDto;
import com.ruoyi.training.mapper.*;
import com.ruoyi.training.service.IExaminationControlService;
import com.ruoyi.training.util.xuehua.SnowflakeIdUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ExaminationControlServiceImpl implements IExaminationControlService {
    @Autowired
    private ClassStudentMapper classStudentMapper;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private StudentsMapper studentsMapper;
    
    @Autowired
    private TrainingClassMapper trainingClassMapper;

    @Autowired
    private RegistrationMapper registrationMapper;

    @Autowired
    private ExaminationControlMapper examinationControlMapper;

    @Autowired
    private ExamScheduleMapper examScheduleMapper;

    private SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(5,8);
    /**
     * 获取试卷信息
     * @param trainingClassId
     * @return
     */
    @Override
    public ExamPaperInfoDto getClassExam(String trainingClassId) {
        Long userId = SecurityUtils.getLoginUser().getUserid();
        R<SysUser> userInfoById = remoteUserService.getUserInfoById(userId, SecurityConstants.INNER);
        String studentId = userInfoById.getData().getStudentId();
//        Students students = studentsMapper.checkUserIdNumber(userInfoById.getData().getIdNumber());
        TrainingClass trainingClass = trainingClassMapper.selectTrainingClassByTrainingClassId(trainingClassId);
        String[] split = trainingClass.getExamPaperIds().split(",");
        String paperConfigId = null;
        String trainingProjectId = null;
        String trainingProjectName = null;
        // 通过班级id和学生id查询班级学生信息
        ClassStudent classStudent = classStudentMapper.selectClassStudentsByCondition(trainingClassId, studentId);
        if (classStudent != null) {
            RegistrationDto registrationDto = registrationMapper.selectRegistrationByRegistrationId(classStudent.getRegistrationId());
            for (String s : split) {
                PaperConfig paperConfig = examinationControlMapper.selectPaperConfigByPaperConfigId(s);
                if (registrationDto.getProjectId().equals(paperConfig.getTrainingProjectId())){
                    paperConfigId = paperConfig.getPaperConfigId();
                    trainingProjectId = paperConfig.getTrainingProjectId();
                    trainingProjectName = paperConfig.getProjectMap();
                }
            }
        }
        ExamPaper examPaper = null;
        ExamRecord examRecordDb = examinationControlMapper.selectExamRecordByCondition(trainingClassId, studentId);
        if (examRecordDb != null) {
            // 刷新网页时不再随机获取试卷
            examPaper = examinationControlMapper.selectExamPaperByExamPaperId(examRecordDb.getExamPaperId());
        }else {
            // 无进行中记录：判断是否为补考（查询不合格记录）
            List<ExamRecord> failedExamRecords = examinationControlMapper.selectFailedExamRecords(
                    trainingClassId, studentId);

            // 收集已考过的试卷ID（补考时排除）
            Set<String> excludedPaperIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(failedExamRecords)) {
                excludedPaperIds = failedExamRecords.stream()
                        .filter(Objects::nonNull)
                        .map(ExamRecord::getExamPaperId)
                        .collect(Collectors.toSet());
            }
            // 查询该配置下的所有试卷
            List<ExamPaper> examPaperList = examinationControlMapper.selectExamPaperByPaperConfigId(paperConfigId);

            // 过滤：排除已考过的试卷（补考场景）
            Set<String> finalExcludedPaperIds = excludedPaperIds;
            List<ExamPaper> availablePapers = examPaperList.stream()
                    .filter(paper -> !finalExcludedPaperIds.contains(paper.getExamPaperId()))
                    .collect(Collectors.toList());

            // 从可用试卷中随机选择一张
            int randomIndex = new Random().nextInt(availablePapers.size());
            examPaper = availablePapers.get(randomIndex);
        }

        ExamPaperInfoDto examPaperInfoDto = new ExamPaperInfoDto();
        BeanUtils.copyProperties(examPaper, examPaperInfoDto);
        List<Question> questionList = new ArrayList<>();
        // 获取试卷中的问题
        List<PaperQuestionRelation> paperQuestionRelationList = examinationControlMapper.selectPaperQuestionRelationByPaperId(examPaper.getExamPaperId());
        for (PaperQuestionRelation paperQuestionRelation : paperQuestionRelationList) {
            Question question = examinationControlMapper.selectQuestionByQuestionId(paperQuestionRelation.getQuestionId());
            List<QuestionOption> questionOptionList = examinationControlMapper.selectQuestionOptionByQuestionId(question.getQuestionId());
            question.setQuestionOptionList(questionOptionList);
            questionList.add(question);
        }
        // 查询个人所有考试记录
        List<ExamRecord> examRecordList = examinationControlMapper.selectExamRecordByTrainingClassIdAndStudentId(trainingClassId, studentId);

        examPaperInfoDto.setStudentId(studentId);
        examPaperInfoDto.setQuestionList(questionList);
        examPaperInfoDto.setTrainingProjectId(trainingProjectId);
        examPaperInfoDto.setTrainingProjectName(trainingProjectName);
        if (examRecordDb == null){
            ExamRecord examRecord = new ExamRecord();
            examRecord.setExamPaperId(examPaper.getExamPaperId());
            examRecord.setStudentId(studentId);
            examRecord.setTrainingClassId(trainingClassId);
            examRecord.setTrainingProjectId(trainingProjectId);
            examRecord.setExamStatus("2");
            examRecord.setExamStartTime(DateUtils.getNowDate());
            if (examRecordList.size() >= 1){
                examRecord.setMakeUpMark("补考");
            }
            try {
                examRecord.setExamIp(InetAddress.getLocalHost().getHostAddress());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            examRecord.setTrainingClassName(trainingClass.getTrainingClassName());
            examRecord.setTrainingProjectName(trainingProjectName);
            examRecord.setExamRecordId(String.valueOf(snowflakeIdUtils.nextId()));
            examRecord.setCreateTime(DateUtils.getNowDate());
            examinationControlMapper.insertExamRecord(examRecord);
        }
        return examPaperInfoDto;
    }

    /**
     * 保存考试结果
     * @param examinationResultVo
     * @return
     */
    @Override
    public ExaminationResultDto saveExamResult(ExaminationResultVo examinationResultVo) {
        if (examinationResultVo == null || examinationResultVo.getExamPaperId() == null) {
            throw new IllegalArgumentException("考试参数或试卷ID不能为空");
        }
        ExaminationResultDto examinationResultDto = new ExaminationResultDto();
        // 通过试卷id查询试卷
        ExamPaper examPaper = examinationControlMapper.selectExamPaperByExamPaperId(examinationResultVo.getExamPaperId());
        if (examPaper == null) {
            throw new IllegalArgumentException("试卷不存在，ID：" + examPaper.getExamPaperId());
        }
        // 通过试卷配置id查询试卷配置
        PaperConfig paperConfig = examinationControlMapper.selectPaperConfigByPaperConfigId(examPaper.getPaperConfigId());
        // 查询考试安排信息通过班级id和考试配置信息
        ExamSchedule examSchedule = examScheduleMapper.selectExamScheduleByTrainingClassIdAndPaperConfigId(examPaper.getTrainingClassId(), examPaper.getPaperConfigId());
        // 通过试卷配置id查询题组信息
        List<PaperConfigGroup> paperConfigGroupList = examinationControlMapper.selectPaperConfigGroupByPaperConfigId(examPaper.getPaperConfigId());
        int totalScore = 0;
        Map<String, PaperConfigGroup> questionIdToConfigGroup = new HashMap<>(); // 问题ID到题组配置的映射
        List<String> allQuestionIds = new ArrayList<>(); // 收集所有问题ID用于批量查询
        for (PaperConfigGroup paperConfigGroup : paperConfigGroupList) {
            List<QuestionGroupRelation> questionGroupRelationList = examinationControlMapper.selectQuestionGroupRelationByGroupId(paperConfigGroup.getGroupId());
            // 获取题组中的已关联的问题id
            List<String> questionIds = questionGroupRelationList.stream().map(QuestionGroupRelation::getQuestionId).collect(Collectors.toList());
            // 记录问题与题组的关联
            for (String questionId : questionIds) {
                questionIdToConfigGroup.put(questionId, paperConfigGroup);
                allQuestionIds.add(questionId);
            }
        }
        List<AnswerRecord> answerRecords = new ArrayList<>();
        Map<String, Question> questionMap = new HashMap<>();
        if (!allQuestionIds.isEmpty()) {
            List<Question> questions = examinationControlMapper.selectQuestionsByIds(allQuestionIds);
            for (Question question : questions) {
                questionMap.put(question.getQuestionId(), question);
            }
        }
        // 查询个人所有考试记录
        List<ExamRecord> examRecordList = examinationControlMapper.selectExamRecordByTrainingClassIdAndStudentId(examinationResultVo.getTrainingClassId(), examinationResultVo.getStudentId());
        // 查询在考试记录中考试状态为考试中的考试记录
        ExamRecord examRecordDb = examinationControlMapper.selectExamRecordByCondition(examinationResultVo.getTrainingClassId(), examinationResultVo.getStudentId());
        for (AnswerVo answerVo : examinationResultVo.getQuestionAnswerList()) {
            String questionId = answerVo.getQuestionId();
            // 获取问题对应的题组配置和问题详情
            PaperConfigGroup configGroup = questionIdToConfigGroup.get(questionId);
            Question question = questionMap.get(questionId);
            // 判断答案正确性（使用Objects.equals避免空指针）
            boolean isAnswerCorrect = Objects.equals(question.getAnswer(), answerVo.getAnswer());
            AnswerRecord answerRecord = new AnswerRecord();
            if (isAnswerCorrect) {
                // 累加分数（题组配置中的分值）
                totalScore += configGroup.getPropositionCount().intValue();
                answerRecord.setActualScore(String.valueOf(configGroup.getPropositionCount()));
                answerRecord.setAnswerType("1");
            }else {
                answerRecord.setActualScore("0");
                answerRecord.setAnswerType("2");
            }
            answerRecord.setExamRecordId(examRecordDb.getExamRecordId());
            answerRecord.setAnswerRecordId(String.valueOf(snowflakeIdUtils.nextId()));
            examinationResultDto.setScore(totalScore);
            answerRecord.setExamPaperId(examinationResultVo.getExamPaperId());
            answerRecord.setQuestionId(questionId);
            answerRecord.setAnswer(answerVo.getAnswer());
            answerRecord.setCreateBy(SecurityUtils.getUsername());
            answerRecord.setCreateTime(DateUtils.getNowDate());
            answerRecord.setStudentId(examinationResultVo.getStudentId());

            answerRecords.add(answerRecord);
        }
        examinationControlMapper.insertAnswerRecordBatch(answerRecords);
        if (examRecordDb != null) {
        if (totalScore >= examSchedule.getExamPassScore()){
            examinationResultDto.setExamResult("1");
        }else {
            examinationResultDto.setExamResult("2");
            examinationResultDto.setMakeUpStatus("1");
            if (examRecordList.size() >= examSchedule.getExamTimes()){
                examRecordDb.setMakeUpStatus("2");
            }else {
                examinationResultDto.setMakeUpStatus("1");
            }
        }

            examRecordDb.setUpdateBy(SecurityUtils.getUsername());
            examRecordDb.setUpdateTime(DateUtils.getNowDate());
            examRecordDb.setTotalScore(String.valueOf(totalScore));
            examRecordDb.setTheoryResult(examinationResultDto.getExamResult());
            examRecordDb.setExamResult(examinationResultDto.getExamResult());
            examRecordDb.setMakeUpStatus(examinationResultDto.getMakeUpStatus());
            examRecordDb.setExamStatus("0");
            examRecordDb.setExamEndTime(DateUtils.getNowDate());
            examRecordDb.setActualDuration(DateUtils.getBetweenMinutes(examRecordDb.getExamEndTime(), examRecordDb.getExamStartTime()).toString());
            examinationControlMapper.updateExamRecord(examRecordDb);
        }
        //提交成功后修改班级学员表中的考试状态——2-已考试
        //通过班级id、学员id、项目id查询出对应的信息，修改对应的考试状态
        //封装查询条件
        ClassStudent classStudent = new ClassStudent();
        if (examRecordDb.getTrainingProjectId() != null && !"".equals(examRecordDb.getTrainingProjectId())){
            classStudent.setProjectId(examRecordDb.getTrainingProjectId());
        }
        if (examRecordDb.getStudentId() != null && !"".equals(examRecordDb.getStudentId())){
            classStudent.setStudentId(examRecordDb.getStudentId());
        }
        if (examRecordDb.getTrainingClassId() != null && !"".equals(examRecordDb.getTrainingClassId())){
            classStudent.setTrainingClassId(examRecordDb.getTrainingClassId());
        }
        List<ClassStudent> classStudentList = classStudentMapper.selectClassStudentList(classStudent);
        if (!classStudentList.isEmpty()){
            ClassStudent classStudent1 = classStudentList.get(0);
            //修改考试状态为已考试
            classStudent1.setExamStatus("2");
            classStudentMapper.updateClassStudent(classStudent1);
        }
        return examinationResultDto;
    }


    /**
     * 生成试卷
     * @param examSchedule
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int generatedPaper(ExamSchedule examSchedule) {
        int result = 0;
        PaperConfig paperConfig = examinationControlMapper.selectPaperConfigByPaperConfigId(examSchedule.getPaperConfigId());
        if (examSchedule.getCounts() > 0){
            for (int i = 0; i < examSchedule.getCounts(); i++) {
                // 试卷信息
                ExamPaper examPaper = new ExamPaper();
                examPaper.setExamPaperId(String.valueOf(snowflakeIdUtils.nextId()));
                examPaper.setCreateBy(SecurityUtils.getUsername());
                examPaper.setCreateTime(DateUtils.getNowDate());
                examPaper.setDelFlag("0");
                examPaper.setExamStartTime(examSchedule.getExamStartTime());
                examPaper.setExamEndTime(examSchedule.getExamEndTime());
                examPaper.setExamDuration(String.valueOf(examSchedule.getExamDuration()));
                examPaper.setPaperConfigId(paperConfig.getPaperConfigId());
                examPaper.setExamPaperName(paperConfig.getPaperConfigName() + i);
                examPaper.setExamNotes(examSchedule.getRemark());
                examPaper.setTrainingClassId(examSchedule.getTrainingClassId());
                boolean hasQuestions = false;
                if (paperConfig != null) {
                    List<PaperConfigGroup> paperConfigGroupList = examinationControlMapper.selectPaperConfigGroupByPaperConfigId(paperConfig.getPaperConfigId());
                    if (CollectionUtils.isNotEmpty(paperConfigGroupList)) {
                        for (PaperConfigGroup paperConfigGroup : paperConfigGroupList) {
                            // 获取题组信息
                            List<QuestionGroupRelation> questionGroupRelationList = examinationControlMapper.selectQuestionGroupRelationByGroupId(paperConfigGroup.getGroupId());
                            // 获取题组关联的题目
                            List<String> allQuestionIds = questionGroupRelationList.stream().map(QuestionGroupRelation::getQuestionId).collect(Collectors.toList());
                            // 根据题量随机抽取题目
                            List<String> questionIds = randomSelect(allQuestionIds, paperConfigGroup.getPropositionCount());
                            if (StringUtils.isNotEmpty(questionIds)){
                                hasQuestions = true;
                                String questionType = paperConfigGroup.getGroupType();
                                // 批量插入关联
                                List<PaperQuestionRelation> relations = buildPaperQuestionRelations(examPaper.getExamPaperId(), questionIds, questionType);
                                examinationControlMapper.batchInsertRelation(relations);
                            }
                        }
                    }
                }
                if (!hasQuestions){
                    continue;
                }
                examinationControlMapper.insertExamPaper(examPaper);
            }
            ExamPaper examPaperVo = new ExamPaper();
            examPaperVo.setTrainingClassId(examSchedule.getTrainingClassId());
            examPaperVo.setPaperConfigId(examSchedule.getPaperConfigId());
            List<ExamPaper> examPapers = examinationControlMapper.selectExamPaperList(examPaperVo);
            result = examPapers.size();
        }
        return result;
    }

    private List<PaperQuestionRelation> buildPaperQuestionRelations(String examPaperId, List<String> questionIds, String questionType) {
        // 按题目抽取顺序，分配 groupSort（1,2,3...）
        List<PaperQuestionRelation> relations = new ArrayList<>();
        for (int i = 0; i < questionIds.size(); i++) {
            String questionId = questionIds.get(i);
            PaperQuestionRelation relation = new PaperQuestionRelation();
            relation.setPaperQuestionId(String.valueOf(snowflakeIdUtils.nextId()));
            relation.setExamPaperId(examPaperId);
            relation.setQuestionId(questionId);
            relation.setQuestionType(questionType);
            // 核心：同一题型内，按抽取顺序从1开始编号
            relation.setQuestionSort(Long.valueOf(i + 1));

            relations.add(relation);
        }
        return relations;
    }

    private List<String> randomSelect(List<String> allQuestionIds, Long propositionCount) {
        if (CollectionUtils.isEmpty(allQuestionIds)) {
            return Collections.emptyList();
        }
        // 若需要的数量大于总数量，返回全部
        if (propositionCount >= allQuestionIds.size()) {
            return new ArrayList<>(allQuestionIds);
        }
        // 随机打乱并截取前propositionCount个
        List<String> shuffled = new ArrayList<>(allQuestionIds);
        Collections.shuffle(shuffled);
        return shuffled.subList(0, propositionCount.intValue());
    }
}
